/*
 * Copyright (c) 2009-2024 Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*============================ INCLUDES ======================================*/

#if defined(_RTE_)
#   include "RTE_Components.h"
#endif

#if defined(RTE_Acceleration_Arm_2D_Helper_PFB)

#include "arm_2d.h"

#ifdef RTE_Acceleration_Arm_2D_Scene1

#define __USER_SCENE1_IMPLEMENT__
#include "arm_2d_scene_1.h"
#include "arm_2d_scenes.h"
#include "arm_2d_helper.h"
#include "arm_2d_example_controls.h"

#include <stdlib.h>
#include <string.h>

#if defined(__clang__)
#   pragma clang diagnostic push
#   pragma clang diagnostic ignored "-Wunknown-warning-option"
#   pragma clang diagnostic ignored "-Wreserved-identifier"
#   pragma clang diagnostic ignored "-Wsign-conversion"
#   pragma clang diagnostic ignored "-Wpadded"
#   pragma clang diagnostic ignored "-Wcast-qual"
#   pragma clang diagnostic ignored "-Wcast-align"
#   pragma clang diagnostic ignored "-Wmissing-field-initializers"
#   pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#   pragma clang diagnostic ignored "-Wmissing-prototypes"
#   pragma clang diagnostic ignored "-Wunused-variable"
#   pragma clang diagnostic ignored "-Wgnu-statement-expression"
#   pragma clang diagnostic ignored "-Wdeclaration-after-statement"
#   pragma clang diagnostic ignored "-Wunused-function"
#   pragma clang diagnostic ignored "-Wmissing-declarations"  
#elif __IS_COMPILER_ARM_COMPILER_5__
#   pragma diag_suppress 64,177
#elif __IS_COMPILER_IAR__
#   pragma diag_suppress=Pa089,Pe188,Pe177,Pe174
#elif __IS_COMPILER_GCC__
#   pragma GCC diagnostic push
#   pragma GCC diagnostic ignored "-Wformat="
#   pragma GCC diagnostic ignored "-Wpedantic"
#   pragma GCC diagnostic ignored "-Wunused-function"
#   pragma GCC diagnostic ignored "-Wunused-variable"
#   pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
#endif

/*============================ MACROS ========================================*/

#if __GLCD_CFG_COLOUR_DEPTH__ == 8

#   define c_tileCMSISLogo          c_tileCMSISLogoGRAY8

#elif __GLCD_CFG_COLOUR_DEPTH__ == 16

#   define c_tileCMSISLogo          c_tileCMSISLogoRGB565

#elif __GLCD_CFG_COLOUR_DEPTH__ == 32

#   define c_tileCMSISLogo          c_tileCMSISLogoCCCA8888
#else
#   error Unsupported colour depth!
#endif

/*============================ MACROFIED FUNCTIONS ===========================*/
#undef this
#define this (*ptThis)

/*============================ TYPES =========================================*/
/*============================ GLOBAL VARIABLES ==============================*/
static uint16_t button_draw_time = 0;


extern uint16_t key_num ;
//static void key_board_run(arm_2d_scene_t *ptScene);



extern const arm_2d_tile_t c_tileshitouRGB565;
extern const arm_2d_tile_t c_tilechaodiRGB565;
extern const arm_2d_tile_t c_tileren01RGB565;
extern const arm_2d_tile_t c_tileren02RGB565;
extern const arm_2d_tile_t c_tileren03RGB565;
extern const arm_2d_tile_t c_tilelvshitouRGB565;
extern const arm_2d_tile_t c_tileshuRGB565;
extern const arm_2d_tile_t c_tilexueshan01RGB565;
extern const arm_2d_tile_t c_tilexueshan02RGB565;
extern const arm_2d_tile_t c_tilezhidanRGB565;

extern const arm_2d_tile_t c_tileren21RGB565;
extern const arm_2d_tile_t c_tileren22RGB565;
extern const arm_2d_tile_t c_tileren23RGB565;
extern const arm_2d_tile_t c_tileren24RGB565;

extern const arm_2d_tile_t c_tilexiaoren1RGB565;
extern const arm_2d_tile_t c_tilexiaoren2RGB565;
extern const arm_2d_tile_t c_tilexiaoren3RGB565;
extern const arm_2d_tile_t c_tilexiaoren4RGB565;

extern const arm_2d_tile_t c_tilezd01RGB565;
extern const arm_2d_tile_t c_tilezd02RGB565;

const arm_2d_tile_t*  ren_tile[3] = {&c_tileren01RGB565,&c_tileren02RGB565,&c_tileren03RGB565};

const arm_2d_tile_t*  ren_jump_tile[4] = {&c_tileren21RGB565,&c_tileren22RGB565,&c_tileren23RGB565,&c_tileren24RGB565};

const arm_2d_tile_t*  xiao_ren_tile[4] = {&c_tilexiaoren1RGB565,&c_tilexiaoren2RGB565,&c_tilexiaoren3RGB565,&c_tilexiaoren4RGB565};

const arm_2d_tile_t*  zd_tile[2] = {&c_tilezd01RGB565,&c_tilezd02RGB565};

void draw_my_Soul_Douluo(void *pTarget,                                 
                                const arm_2d_tile_t *ptTile,                   
                                bool bIsNewFrame);
                                
void Soul_Douluo_init();  
void Soul_Douluo_move();
uint32_t get_move_iX();                                
 
/*============================ PROTOTYPES ====================================*/
/*============================ LOCAL VARIABLES ===============================*/

/*! define dirty regions */
IMPL_ARM_2D_REGION_LIST(s_tDirtyRegions, static)

    /* a dirty region to be specified at runtime*/
    ADD_REGION_TO_LIST(s_tDirtyRegions,
        0  /* initialize at runtime later */
    ),
    
    /* add the last region:
        * it is the top left corner for text display 
        */
    ADD_LAST_REGION_TO_LIST(s_tDirtyRegions,
        .tLocation = {
            .iX = 0,
            .iY = 0,
        },
        .tSize = {
            .iWidth = 320,
            .iHeight = 240,
        },
    ),

END_IMPL_ARM_2D_REGION_LIST(s_tDirtyRegions)

/*============================ IMPLEMENTATION ================================*/

static void __on_scene1_load(arm_2d_scene_t *ptScene)
{
    user_scene_1_t *ptThis = (user_scene_1_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}

static void __on_scene1_depose(arm_2d_scene_t *ptScene)
{
    user_scene_1_t *ptThis = (user_scene_1_t *)ptScene;
    ARM_2D_UNUSED(ptThis);
    
    ptScene->ptPlayer = NULL;
    
    /* reset timestamp */
    arm_foreach(int64_t,this.lTimestamp, ptItem) {
        *ptItem = 0;
    }

    if (!this.bUserAllocated) {
        __arm_2d_free_scratch_memory(ARM_2D_MEM_TYPE_UNSPECIFIED, ptScene);
    }
}

/*----------------------------------------------------------------------------*
 * Scene 1                                                                    *
 *----------------------------------------------------------------------------*/

static void __on_scene1_background_start(arm_2d_scene_t *ptScene)
{
    user_scene_1_t *ptThis = (user_scene_1_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}

static void __on_scene1_background_complete(arm_2d_scene_t *ptScene)
{
    user_scene_1_t *ptThis = (user_scene_1_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}


static void __on_scene1_frame_start(arm_2d_scene_t *ptScene)
{
    user_scene_1_t *ptThis = (user_scene_1_t *)ptScene;
    ARM_2D_UNUSED(ptThis);
    
    Soul_Douluo_move();  

}
void set_emit_flag();
static void __on_scene1_frame_complete(arm_2d_scene_t *ptScene)
{
    user_scene_1_t *ptThis = (user_scene_1_t *)ptScene;
    ARM_2D_UNUSED(ptThis);
    // key_board_run(ptScene);
    /* switch to next scene after 3s */
    if (arm_2d_helper_is_time_out(500, &this.lTimestamp[0])) {
        //arm_2d_scene_player_switch_to_next_scene(ptScene->ptPlayer);
			  //button_draw_time++;
        set_emit_flag();
    }
}

static void __before_scene1_switching_out(arm_2d_scene_t *ptScene)
{
    user_scene_1_t *ptThis = (user_scene_1_t *)ptScene;
    ARM_2D_UNUSED(ptThis);

}

static void draw_my_catalogue_list(void *pTarget,                                  
                 const arm_2d_tile_t *ptTile,                   
                 arm_2d_region_t Region,
								 bool bIsNewFrame){
									 
		draw_round_corner_box(  ptTile, 
                                    &Region, 
                                    GLCD_COLOR_WHITE, 
                                    255,
                                    bIsNewFrame);
            
            
            
		draw_round_corner_border(   ptTile, 
																&Region, 
																GLCD_COLOR_BLACK, 
																(arm_2d_border_opacity_t)
																		{32, 32, 255-64, 255-64},
																(arm_2d_corner_opacity_t)
																		{0, 128, 128, 128});								 
									 
}

static
IMPL_PFB_ON_DRAW(__pfb_draw_scene1_handler)
{
    user_scene_1_t *ptThis = (user_scene_1_t *)pTarget;
    arm_2d_size_t tScreenSize = ptTile->tRegion.tSize;

    ARM_2D_UNUSED(ptTile);
    ARM_2D_UNUSED(bIsNewFrame);
    ARM_2D_UNUSED(tScreenSize);
    
    arm_2d_canvas(ptTile, __top_canvas) {
    /*-----------------------draw the foreground begin-----------------------*/
        
        /* following code is just a demo, you can remove them */
        
        arm_2d_fill_colour(ptTile, NULL, GLCD_COLOR_BLACK);
        do{
            arm_2d_region_t myRegion ={
                .tLocation = {.iX = 0,.iY = 240-25},
                .tSize = {.iHeight = 25,.iWidth = 320},
            };
            arm_2d_fill_colour(ptTile, &myRegion, GLCD_COLOR_BLUE);
        }while(0);
			
			/*draw_my_catalogue( pTarget,                                  
                 ptTile,                   
                  bIsNewFrame);*/

        draw_my_Soul_Douluo(pTarget,                                 
                                ptTile,                   
                                 bIsNewFrame);
        

        /* draw text at the top-left corner */

        arm_lcd_text_set_target_framebuffer((arm_2d_tile_t *)ptTile);
        arm_lcd_text_set_font(&ARM_2D_FONT_6x8.use_as__arm_2d_font_t);
        arm_lcd_text_set_draw_region(NULL);
        arm_lcd_text_set_colour(GLCD_COLOR_RED, GLCD_COLOR_WHITE);
        arm_lcd_text_location(0,0);
        //arm_lcd_puts("Scene 1");
				//arm_lcd_printf("%d",key_num get_move_iX());
        arm_lcd_printf("%d=%d", get_move_iX(),key_num);

    /*-----------------------draw the foreground end  -----------------------*/
    }
    arm_2d_op_wait_async(NULL);

    return arm_fsm_rt_cpl;
}

ARM_NONNULL(1)
user_scene_1_t *__arm_2d_scene1_init(   arm_2d_scene_player_t *ptDispAdapter, 
                                        user_scene_1_t *ptThis)
{
    bool bUserAllocated = false;
    assert(NULL != ptDispAdapter);

    s_tDirtyRegions[dimof(s_tDirtyRegions)-1].ptNext = NULL;

    /* get the screen region */
    arm_2d_region_t tScreen
        = arm_2d_helper_pfb_get_display_area(
            &ptDispAdapter->use_as__arm_2d_helper_pfb_t);

    /* initialise dirty region 0 at runtime
     * this demo shows that we create a region in the centre of a screen(320*240)
     * for a image stored in the tile c_tileCMSISLogoMask
     */
    //arm_2d_align_centre(tScreen, c_tileCMSISLogoMask.tRegion.tSize) {
        //s_tDirtyRegions[0].tRegion = __centre_region;
    //}

    //s_tDirtyRegions[dimof(s_tDirtyRegions)-1].tRegion.tSize.iWidth 
    //                                                    = tScreen.tSize.iWidth;
    
    if (NULL == ptThis) {
        ptThis = (user_scene_1_t *)
                    __arm_2d_allocate_scratch_memory(   sizeof(user_scene_1_t),
                                                        __alignof__(user_scene_1_t),
                                                        ARM_2D_MEM_TYPE_UNSPECIFIED);
        assert(NULL != ptThis);
        if (NULL == ptThis) {
            return NULL;
        }
    } else {
        bUserAllocated = true;
    }
    memset(ptThis, 0, sizeof(user_scene_1_t));

    *ptThis = (user_scene_1_t){
        .use_as__arm_2d_scene_t = {

            /* the canvas colour */
            .tCanvas = {GLCD_COLOR_WHITE}, 

            /* Please uncommon the callbacks if you need them
             */
            .fnOnLoad       = &__on_scene1_load,
            .fnScene        = &__pfb_draw_scene1_handler,
            .ptDirtyRegion  = (arm_2d_region_list_item_t *)s_tDirtyRegions,
            

            //.fnOnBGStart    = &__on_scene1_background_start,
            //.fnOnBGComplete = &__on_scene1_background_complete,
            .fnOnFrameStart = &__on_scene1_frame_start,
            //.fnBeforeSwitchOut = &__before_scene1_switching_out,
            .fnOnFrameCPL   = &__on_scene1_frame_complete,
            .fnDepose       = &__on_scene1_depose,

            .bUseDirtyRegionHelper = false,
        },
        .bUserAllocated = bUserAllocated,
    };

    /* ------------   initialize members of user_scene_1_t begin ---------------*/


    /* ------------   initialize members of user_scene_1_t end   ---------------*/

    arm_2d_scene_player_append_scenes(  ptDispAdapter, 
                                        &this.use_as__arm_2d_scene_t, 
                                        1);
    Soul_Douluo_init();                                     

    return ptThis;
}

//===========================================================================
//===========================================================================
//===========================================================================
//===========================================================================
//===========================================================================

#if 1
#define Soul_Douluo_LEN 58
#define Soul_Douluo_GAME_WIDTH 320

#define Soul_Douluo_LEVEL_1_IY  125
#define Soul_Douluo_LEVEL_2_IY  160
#define Soul_Douluo_LEVEL_3_IY  195
#define Soul_Douluo_LEVEL_4_IY  230

#define Soul_Douluo_PEOPLE_IX  30
#define Soul_Douluo_PEOPLE_WIDTH 43
typedef struct{
    uint32_t iX;
    uint16_t iWidth;
    uint8_t layer;    

}Soul_Douluo_map_t;

#define Soul_Douluo_MAP_NUMS (sizeof(Soul_Douluo_map)/sizeof(Soul_Douluo_map[0]))

const Soul_Douluo_map_t Soul_Douluo_map[]={
    {.iX = 0,.iWidth = 58*10,.layer = 1},
    {.iX = 10,.iWidth = 58*1,.layer = 4},
    {.iX = 80,.iWidth = 58*2,.layer = 3},
    {.iX = 220,.iWidth = 58*2,.layer = 2},
    
    {.iX = 58*10,.iWidth = 58*2,.layer = 2},
    {.iX = 58*12,.iWidth = 58*2,.layer = 3},    
    {.iX = 58*14,.iWidth = 58*1,.layer = 4},
    {.iX = 58*15,.iWidth = 58*2,.layer = 3},
    
    
    {.iX = 58*17+30,.iWidth = 58*100,.layer = 1},
    {.iX = 58*17,.iWidth = 58*2,.layer = 2},
};

typedef struct {
    int16_t iX;
    int16_t iY;
    int8_t  flag;
}Soul_Douluo_bullet_t;
#define Soul_Douluo_bullets_NUM 3
Soul_Douluo_bullet_t Soul_Douluo_bullets[Soul_Douluo_bullets_NUM]={
    {.iX = 0,.iY = 0,.flag = 0},
    {.iX = 0,.iY = 0,.flag = 0},
};

//===============
typedef struct {
    uint32_t iX;
    uint8_t layer;
}Soul_Douluo_enemy_map_t;
//  1038  1266
#define Soul_Douluo_ENEMY_MAP_NUMS (sizeof(Soul_Douluo_enemy_map)/sizeof(Soul_Douluo_enemy_map[0]))
    
const Soul_Douluo_enemy_map_t  Soul_Douluo_enemy_map[] ={
    {.iX = 402,.layer = 1,},
    {.iX = 543,.layer = 1,},
    //{.iX = 1233,.layer = 1,},
    {.iX = 1365,.layer = 1,},
    {.iX = 1593,.layer = 1,},
    {.iX = 1869,.layer = 1,},
};
typedef struct {
    uint32_t iX;
    int16_t iY;
    uint8_t flag;
    uint8_t level;
}Soul_Douluo_enemy_t;

#define Soul_Douluo_ENEMY_NUM 10
Soul_Douluo_enemy_t Soul_Douluo_enemys[Soul_Douluo_ENEMY_NUM];
typedef struct {
    uint32_t move_iX;
    uint32_t find_enemy_iX;
    uint16_t map_num1;
    uint16_t map_num2;
    uint8_t inc_iX;
    uint8_t move_down_flag;
    uint16_t people_iY;
    uint8_t current_map_num;
    uint8_t current_map_num_flag;
    
    uint8_t jump_flag;
    uint8_t find_jump_map_num_flag;
    
    uint8_t pause_flag ;
    
    uint8_t emit_flag;
}Soul_Douluo_Op_t;

Soul_Douluo_Op_t Soul_Douluo_Op;
void Soul_Douluo_init(){
    char i;
    Soul_Douluo_Op.inc_iX = 3;
    Soul_Douluo_Op.move_iX = 0;
    
    Soul_Douluo_Op.map_num1 = 0;
    Soul_Douluo_Op.map_num2 = 1;
    
    Soul_Douluo_Op.move_down_flag = 0;
    Soul_Douluo_Op.people_iY = Soul_Douluo_LEVEL_1_IY - 55;
    Soul_Douluo_Op.current_map_num = 0;
    
    Soul_Douluo_Op.jump_flag = 0;
    
    Soul_Douluo_Op.pause_flag = 0;
    Soul_Douluo_Op.emit_flag = 0;
    
    for(i = 0; i < Soul_Douluo_bullets_NUM; i++ ){
        Soul_Douluo_bullets[i].flag = 0;
    }
    //Soul_Douluo_enemys[Soul_Douluo_ENEMY_NUM]
    for(i = 0; i < Soul_Douluo_ENEMY_NUM; i++ ){
        Soul_Douluo_enemys[i].flag = 0;
    }
    Soul_Douluo_Op.find_enemy_iX = 0;
}


uint8_t check_lines_Intersection(uint32_t ix1,uint32_t iwidth1,uint32_t ix2,uint32_t iwidth2){
    if(ix1 > ix2 ){
        if(ix1 <= (ix2 + iwidth2)){
            return 1;
        }
    }else{
        if((ix2 - ix1) <= iwidth1){
            return 1;
        }
    }
    return 0;
}
void Soul_Douluo_find_map(){
    uint16_t i,j;//Soul_Douluo_GAME_WIDTH
    uint16_t num = Soul_Douluo_MAP_NUMS;//sizeof(Soul_Douluo_map)/sizeof(Soul_Douluo_map[0]);
    Soul_Douluo_Op.map_num1 = num;
    for(i = 0;i < num; i++){
        if(check_lines_Intersection(Soul_Douluo_map[i].iX,Soul_Douluo_map[i].iWidth,Soul_Douluo_Op.move_iX,Soul_Douluo_GAME_WIDTH)){
            Soul_Douluo_Op.map_num1 = i;
            break;
        }
        
    }
    Soul_Douluo_Op.map_num2 = 1;
     for(i = 0;i < num; i++){
        if(check_lines_Intersection(Soul_Douluo_map[i].iX,Soul_Douluo_map[i].iWidth,Soul_Douluo_Op.move_iX,Soul_Douluo_GAME_WIDTH)){
            Soul_Douluo_Op.map_num2 = i;
            //break;
        }
        
    }
    
}
uint8_t Soul_Douluo_find_current_map_num(){
    uint16_t i;
    uint32_t people_iX = Soul_Douluo_PEOPLE_IX + Soul_Douluo_PEOPLE_WIDTH + Soul_Douluo_Op.move_iX;
    
    for(i = 0; i < Soul_Douluo_MAP_NUMS;i++){
        if(check_lines_Intersection(Soul_Douluo_map[i].iX,Soul_Douluo_map[i].iWidth,people_iX,2)){
            if(Soul_Douluo_map[i].layer > Soul_Douluo_map[Soul_Douluo_Op.current_map_num].layer){
                Soul_Douluo_Op.current_map_num = i;
                return 1;
            }   
        }
    }
     return 0;
}

void Soul_Douluo_move_down(){
    enum{
        START = 0,
        CHECK_MOVE_DOWN ,
        MOVE_DOWN ,
        MOVE_DOWN_STOP,
    };  
    static int8_t state = START;
    switch(state){
        case START:
            state = CHECK_MOVE_DOWN;    
        break;
        case CHECK_MOVE_DOWN:
            if(Soul_Douluo_Op.current_map_num == 0xff){
                break;
            }
            if(((Soul_Douluo_PEOPLE_IX + Soul_Douluo_PEOPLE_WIDTH + Soul_Douluo_Op.move_iX) >=
                (Soul_Douluo_map[Soul_Douluo_Op.current_map_num].iX + Soul_Douluo_map[Soul_Douluo_Op.current_map_num].iWidth))){
                if(((Soul_Douluo_PEOPLE_IX + Soul_Douluo_PEOPLE_WIDTH + Soul_Douluo_Op.move_iX) -
                    (Soul_Douluo_map[Soul_Douluo_Op.current_map_num].iX + Soul_Douluo_map[Soul_Douluo_Op.current_map_num].iWidth)) >= (Soul_Douluo_PEOPLE_WIDTH>>1)){    
                        Soul_Douluo_Op.current_map_num_flag = Soul_Douluo_find_current_map_num();
                        if(0 == Soul_Douluo_Op.current_map_num_flag){
                            Soul_Douluo_Op.current_map_num = 0xff;
                        }
                        Soul_Douluo_Op.move_down_flag = 1;
                        state = MOVE_DOWN;   
                }
            }    
        break;
        case MOVE_DOWN:
            //Soul_Douluo_Op.current_map_num++;
            if(0 == Soul_Douluo_Op.current_map_num_flag){
                Soul_Douluo_Op.current_map_num_flag = Soul_Douluo_find_current_map_num();
            }
            Soul_Douluo_Op.people_iY += 7;
            if(Soul_Douluo_Op.current_map_num_flag){
                if(2 == Soul_Douluo_map[Soul_Douluo_Op.current_map_num].layer){
                    if(Soul_Douluo_Op.people_iY >= (Soul_Douluo_LEVEL_2_IY - 55)){
                        Soul_Douluo_Op.people_iY = Soul_Douluo_LEVEL_2_IY - 55;
                        state = MOVE_DOWN_STOP;  
                    }
                }else if(3 == Soul_Douluo_map[Soul_Douluo_Op.current_map_num].layer){
                    //Soul_Douluo_Op.people_iY = Soul_Douluo_LEVEL_3_IY - 55;
                     if(Soul_Douluo_Op.people_iY >= (Soul_Douluo_LEVEL_3_IY - 55)){
                        Soul_Douluo_Op.people_iY = Soul_Douluo_LEVEL_3_IY - 55;
                        state = MOVE_DOWN_STOP;  
                    }
                }else if(4 == Soul_Douluo_map[Soul_Douluo_Op.current_map_num].layer){
                    //Soul_Douluo_Op.people_iY = Soul_Douluo_LEVEL_4_IY - 55;
                    if(Soul_Douluo_Op.people_iY >= (Soul_Douluo_LEVEL_4_IY - 55)){
                        Soul_Douluo_Op.people_iY = Soul_Douluo_LEVEL_4_IY - 55;
                        state = MOVE_DOWN_STOP;  
                    }
                }
            }
            else{
                //Soul_Douluo_Op.people_iY = Soul_Douluo_LEVEL_4_IY - 35;
                if(Soul_Douluo_Op.people_iY >= (Soul_Douluo_LEVEL_4_IY - 35)){
                        Soul_Douluo_Op.people_iY = Soul_Douluo_LEVEL_4_IY - 35;
                        state = MOVE_DOWN_STOP;  
                }
            }                        
        break;
        case MOVE_DOWN_STOP:
            Soul_Douluo_Op.move_down_flag = 0;
            Soul_Douluo_Op.current_map_num_flag = 0;
            state = START; 
        break;
    
    }
}
//int16_t layer_iy[4]={(Soul_Douluo_LEVEL_1_IY - 55),(Soul_Douluo_LEVEL_2_IY - 55),
//                     (Soul_Douluo_LEVEL_3_IY - 55),(Soul_Douluo_LEVEL_4_IY - 55)};
int16_t layer_iY[] = {Soul_Douluo_LEVEL_1_IY-55,
    Soul_Douluo_LEVEL_2_IY-55,
    Soul_Douluo_LEVEL_3_IY-55,
    Soul_Douluo_LEVEL_4_IY-55,
};
uint8_t Soul_Douluo_find_jump_map_num(){
    uint16_t i;
    uint32_t people_iX = Soul_Douluo_PEOPLE_IX + Soul_Douluo_PEOPLE_WIDTH + Soul_Douluo_Op.move_iX;
    
    for(i = 0; i < Soul_Douluo_MAP_NUMS;i++){
        if(check_lines_Intersection(Soul_Douluo_map[i].iX,Soul_Douluo_map[i].iWidth,people_iX-2,2)){
            if(Soul_Douluo_Op.people_iY <= layer_iY[Soul_Douluo_map[i].layer - 1]){
                    Soul_Douluo_Op.current_map_num = i;
                    return 1;
            }            
        }
    }
    return 0;
}
uint8_t Soul_Douluo_find_jump_map_num2(){
    uint16_t i;
    uint32_t people_iX = Soul_Douluo_PEOPLE_IX + Soul_Douluo_PEOPLE_WIDTH + Soul_Douluo_Op.move_iX;
    
    for(i = 0; i < Soul_Douluo_MAP_NUMS;i++){
        if(check_lines_Intersection(Soul_Douluo_map[i].iX,Soul_Douluo_map[i].iWidth,people_iX-2,2)){
            if(1 == Soul_Douluo_map[i].layer){
                if(Soul_Douluo_Op.people_iY <= (Soul_Douluo_LEVEL_1_IY - 55)){
                    Soul_Douluo_Op.current_map_num = i;
                    return 1;
                }
            }
            else if(2 == Soul_Douluo_map[i].layer){
                if(Soul_Douluo_Op.people_iY <= (Soul_Douluo_LEVEL_2_IY - 55)){
                    Soul_Douluo_Op.current_map_num = i;
                    return 1;
                }
            }else if(3 == Soul_Douluo_map[i].layer){
                if(Soul_Douluo_Op.people_iY <= (Soul_Douluo_LEVEL_3_IY - 55)){
                    Soul_Douluo_Op.current_map_num = i;
                    return 1;
                }
            }else if(4 == Soul_Douluo_map[i].layer){
                if(Soul_Douluo_Op.people_iY <= (Soul_Douluo_LEVEL_4_IY - 55)){
                    Soul_Douluo_Op.current_map_num = i;
                    return 1;
                }
            }
   
        }
    }
     return 0;
}
uint8_t Soul_Douluo_check_jump_stop2(){
    if(Soul_Douluo_Op.find_jump_map_num_flag){
        Soul_Douluo_Op.people_iY += 7;
        if(1 == Soul_Douluo_map[Soul_Douluo_Op.current_map_num].layer){
            if(Soul_Douluo_Op.people_iY >= (Soul_Douluo_LEVEL_1_IY - 55)){
                Soul_Douluo_Op.people_iY = (Soul_Douluo_LEVEL_1_IY - 55);
                return 1;
            }
        }else if(2 == Soul_Douluo_map[Soul_Douluo_Op.current_map_num].layer){
            if(Soul_Douluo_Op.people_iY >= (Soul_Douluo_LEVEL_2_IY - 55)){
                Soul_Douluo_Op.people_iY = (Soul_Douluo_LEVEL_2_IY - 55);
                return 1;
            }
        }
        else if(3 == Soul_Douluo_map[Soul_Douluo_Op.current_map_num].layer){
            if(Soul_Douluo_Op.people_iY >= (Soul_Douluo_LEVEL_3_IY - 55)){
                Soul_Douluo_Op.people_iY = (Soul_Douluo_LEVEL_3_IY - 55);
                return 1;
            }
        }else if(4 == Soul_Douluo_map[Soul_Douluo_Op.current_map_num].layer){
            if(Soul_Douluo_Op.people_iY >= (Soul_Douluo_LEVEL_4_IY - 55)){
                Soul_Douluo_Op.people_iY = (Soul_Douluo_LEVEL_4_IY - 55);
                return 1;
            }
        }
        
    }
    return 0;
}

uint8_t Soul_Douluo_check_jump_stop(){
    if(Soul_Douluo_Op.find_jump_map_num_flag){
        Soul_Douluo_Op.people_iY += 7;
        if(Soul_Douluo_Op.people_iY >= layer_iY[Soul_Douluo_map[Soul_Douluo_Op.current_map_num].layer-1]){
                Soul_Douluo_Op.people_iY = layer_iY[Soul_Douluo_map[Soul_Douluo_Op.current_map_num].layer-1];
                return 1;
        }        
    }
    return 0;
}
//========================================


//======64================sin10=sin20=sin30=sin40=sin50=sin60=sin70=sin80=sin90==========
//    char jump_data[9] = {11,  22,   32,   41,   49,   55,   60,   63,   64};
const char jump_data[9] = {11,  11,   10,    9,    8,    6,    5,    3,    1};
void Soul_Douluo_move_jump(){
    enum{
        JUMP_START = 0,
        //MOVE_JUMP ,
        MOVE_JUMP_UP ,
        MOVE_JUMP_DOWN ,
        MOVE_JUMP_STOP,
    }; 
    static char num = 0;
    int16_t iY;
    static int8_t jump_state = JUMP_START; 
    switch(jump_state){
        case JUMP_START:
            if(Soul_Douluo_Op.jump_flag){
                jump_state = MOVE_JUMP_UP; 
            }
            num = 0;
        break;
        case MOVE_JUMP_UP:
            //if(Soul_Douluo_get_jump_inc_up(&iY)){
            //    jump_state = MOVE_JUMP_DOWN; 
            //}else
            Soul_Douluo_Op.people_iY -= jump_data[num];
            num++;
            if(num >= 9){
                num = 0;
                jump_state = MOVE_JUMP_DOWN;                
            }
        break;
        case MOVE_JUMP_DOWN:
            //if(Soul_Douluo_get_jump_inc_down(&iY)){
            //    jump_state = MOVE_JUMP_STOP; 
            //}else
            Soul_Douluo_Op.people_iY += jump_data[8 - num];
            num++;
            Soul_Douluo_Op.find_jump_map_num_flag = Soul_Douluo_find_jump_map_num();
                if(Soul_Douluo_Op.find_jump_map_num_flag){
                    //num = 0;
                    jump_state = MOVE_JUMP_STOP; 
                }
             if(num >= 9){
                num = 0;
                jump_state = MOVE_JUMP_STOP;                
            }
        break;

        case MOVE_JUMP_STOP:
            if(Soul_Douluo_Op.find_jump_map_num_flag){
                //Soul_Douluo_Op.people_iY += 7;
                if(Soul_Douluo_check_jump_stop()){
                    Soul_Douluo_Op.jump_flag = 0;
                    Soul_Douluo_Op.find_jump_map_num_flag = 0;
                    jump_state = JUMP_START;
                }
            }else{
                Soul_Douluo_Op.jump_flag = 0;
                Soul_Douluo_Op.find_jump_map_num_flag = 0;
                jump_state = JUMP_START; 
            }
        break;
    }
}

void Soul_Douluo_emit(){
    char i = 0;
    if(Soul_Douluo_Op.emit_flag){
        Soul_Douluo_Op.emit_flag = 0;
        for(i = 0; i < Soul_Douluo_bullets_NUM; i++){
            if(Soul_Douluo_bullets[i].flag == 0){
                Soul_Douluo_bullets[i].flag = 1;
                Soul_Douluo_bullets[i].iX = Soul_Douluo_PEOPLE_IX + Soul_Douluo_PEOPLE_WIDTH + 10;
                Soul_Douluo_bullets[i].iY = Soul_Douluo_Op.people_iY + 5;
                break;
            }
        }
    }
}

void Soul_Douluo_emit_run(){
    char i = 0;
    for(i = 0; i < Soul_Douluo_bullets_NUM; i++){
        if(Soul_Douluo_bullets[i].flag ){
            Soul_Douluo_bullets[i].iX += 10;
            if(Soul_Douluo_bullets[i].iX >= Soul_Douluo_GAME_WIDTH){
                Soul_Douluo_bullets[i].flag = 0;
            }
        }
    }
}

void auto_key(){
    if(Soul_Douluo_Op.move_iX == 789){
        Soul_Douluo_Op.jump_flag = 1;
    }
    if(Soul_Douluo_Op.move_iX == 903){
        Soul_Douluo_Op.jump_flag = 1;
    }
    if(Soul_Douluo_Op.move_iX == 1029){
        Soul_Douluo_Op.jump_flag = 1;
    }
    if(Soul_Douluo_Op.move_iX == 1164){
        Soul_Douluo_Op.jump_flag = 1;
    }//set_emit_flag();
}
void Soul_Douluo_key_board_run();
void Soul_Douluo_loading_enemy();
void Soul_Douluo_enemy_run();
void Soul_Douluo_wipe_out_the_enemy();
void Soul_Douluo_move(){
    if(Soul_Douluo_Op.pause_flag == 0){
        Soul_Douluo_Op.move_iX += Soul_Douluo_Op.inc_iX;
    }
    Soul_Douluo_find_map();
    Soul_Douluo_key_board_run();
    if(Soul_Douluo_Op.move_down_flag==0){
        Soul_Douluo_move_jump();
    }
    if(Soul_Douluo_Op.jump_flag==0){
        Soul_Douluo_move_down();
    }
    Soul_Douluo_loading_enemy();
    Soul_Douluo_enemy_run();
    
    Soul_Douluo_emit();
    Soul_Douluo_emit_run();
    
    Soul_Douluo_wipe_out_the_enemy();
    auto_key();
}

uint32_t get_move_iX(){
    return Soul_Douluo_Op.move_iX;
}

//===============================================

void Soul_Douluo_add_enemy(uint32_t iX,uint8_t layer){
    int16_t i;
    for(i = 0; i < Soul_Douluo_ENEMY_NUM; i++ ){
        if( 0 == Soul_Douluo_enemys[i].flag){
            Soul_Douluo_enemys[i].flag = 1;
            Soul_Douluo_enemys[i].iX = iX;
            Soul_Douluo_enemys[i].iY = layer_iY[(layer) & 0x03] ;
            Soul_Douluo_enemys[i].level = 100;
            break;
        }
    }
}
void Soul_Douluo_loading_enemy(){//Soul_Douluo_enemy_map[]
    int16_t i;
    uint32_t end_iX = Soul_Douluo_Op.move_iX + Soul_Douluo_GAME_WIDTH;
    for(i = 0; i < Soul_Douluo_ENEMY_MAP_NUMS;i++){
        if((Soul_Douluo_enemy_map[i].iX >= Soul_Douluo_Op.move_iX) && (Soul_Douluo_enemy_map[i].iX <= end_iX)){
            if(Soul_Douluo_enemy_map[i].iX >= Soul_Douluo_Op.find_enemy_iX){
                Soul_Douluo_Op.find_enemy_iX = Soul_Douluo_enemy_map[i].iX + 1;
                Soul_Douluo_add_enemy(Soul_Douluo_enemy_map[i].iX,Soul_Douluo_enemy_map[i].layer-1);
            }
        }
    }
}
void Soul_Douluo_enemy_run(){
    int16_t i;
    for(i = 0; i < Soul_Douluo_ENEMY_NUM; i++ ){
        if( 1 == Soul_Douluo_enemys[i].flag){
            Soul_Douluo_enemys[i].iX -= 3;
        }
    }
}
#define ENEMY_WIDTH 34
void Soul_Douluo_sub_enemy(uint8_t num){

    if( Soul_Douluo_enemys[num].flag){
        Soul_Douluo_enemys[num].flag = 0;
    }
}

void Soul_Douluo_emit_bullets_to_the_enemy(uint8_t num){
    char i;
    arm_2d_region_t bulletsRegion ={
            .tLocation = {.iX = 0,.iY = 0},
            .tSize = {.iHeight = 15,.iWidth = 17},
    };
        
    arm_2d_region_t enemyRegion ={
            .tLocation = {.iX = 0,.iY = 0},
            .tSize = {.iHeight = 43,.iWidth = 34},
    };
    arm_2d_region_t RegionOut;    
                            
    for(i = 0; i < Soul_Douluo_bullets_NUM; i++ ){
        if(Soul_Douluo_bullets[i].flag ){
            bulletsRegion.tLocation.iX = Soul_Douluo_bullets[i].iX;
            bulletsRegion.tLocation.iY = Soul_Douluo_bullets[i].iY;
            enemyRegion.tLocation.iX = Soul_Douluo_enemys[num].iX - Soul_Douluo_Op.move_iX;
            enemyRegion.tLocation.iY = Soul_Douluo_enemys[num].iY;
            
             
            if(arm_2d_region_intersect(  &bulletsRegion ,
                                &enemyRegion,
                                &RegionOut)){
                if(RegionOut.tSize.iHeight * RegionOut.tSize.iHeight >200){
                    if(Soul_Douluo_enemys[num].level < 30){
                        //Soul_Douluo_sub_enemy(num);
                        Soul_Douluo_enemys[num].flag = 2;
                        Soul_Douluo_bullets[i].flag = 0; 
                    }else{
                        Soul_Douluo_enemys[num].level -= 30;
                        Soul_Douluo_bullets[i].flag = 0; 
                    }
                }                    
                                       
            }
        }
    }
}
void Soul_Douluo_wipe_out_the_enemy(){
    int16_t i;
    for(i = 0; i < Soul_Douluo_ENEMY_NUM; i++ ){
        if( 1 == Soul_Douluo_enemys[i].flag){
            if((Soul_Douluo_enemys[i].iX + ENEMY_WIDTH) <= Soul_Douluo_Op.move_iX){
                Soul_Douluo_sub_enemy(i);
            }
            Soul_Douluo_emit_bullets_to_the_enemy(i);    
        }
    }
}

void draw_my_Soul_Douluo(void *pTarget,                                  
                                const arm_2d_tile_t *ptTile,                    
                                bool bIsNewFrame){
    uint8_t map_num = 0;   
    static uint16_t s_num = 0;                                    
    arm_2d_fill_colour(ptTile, NULL, GLCD_COLOR_BLACK);
    do{
        arm_2d_region_t myRegion ={
            .tLocation = {.iX = 0,.iY = 240-25},
            .tSize = {.iHeight = 25,.iWidth = 320},
        };
        arm_2d_fill_colour(ptTile, &myRegion, GLCD_COLOR_BLUE);
    }while(0); 
    
    arm_2d_region_t myMapRegion;

    for(map_num = Soul_Douluo_Op.map_num1;map_num <= Soul_Douluo_Op.map_num2; map_num++){
        switch(Soul_Douluo_map[map_num].layer){
            case 1:
                 myMapRegion.tLocation.iY = Soul_Douluo_LEVEL_1_IY;
                myMapRegion.tSize.iHeight = 90;
            break;
            case 2:
                 myMapRegion.tLocation.iY = Soul_Douluo_LEVEL_2_IY;
                myMapRegion.tSize.iHeight = 70;
            break;    
            case 3:
                myMapRegion.tLocation.iY = Soul_Douluo_LEVEL_3_IY;
                myMapRegion.tSize.iHeight = 40;            
            break;
            case 4:
                 myMapRegion.tLocation.iY = Soul_Douluo_LEVEL_4_IY;
                myMapRegion.tSize.iHeight = 5;
            break;            
        }
        myMapRegion.tLocation.iX = Soul_Douluo_map[map_num].iX - Soul_Douluo_Op.move_iX;
        myMapRegion.tSize.iWidth = Soul_Douluo_map[map_num].iWidth;
        arm_2dp_rgb16_tile_fill_only(NULL,
                            &c_tileshitouRGB565,       
                            ptTile,        
                            &myMapRegion); 
        
        myMapRegion.tLocation.iY -= 22;
        myMapRegion.tSize.iHeight = 22;
        arm_2dp_rgb16_tile_fill_only(NULL,
                                    &c_tilechaodiRGB565,       
                                    ptTile,        
                                    &myMapRegion);
        if(1 == Soul_Douluo_map[map_num].layer){
            //lv shi tou 
            myMapRegion.tLocation.iY -= 12;
            myMapRegion.tSize.iHeight = 12;
            arm_2dp_rgb16_tile_fill_only(NULL,
                                &c_tilelvshitouRGB565,       
                                ptTile,        
                                &myMapRegion);         
            //lv shu             
            myMapRegion.tLocation.iY -= 34;
            myMapRegion.tSize.iHeight = 34;
            arm_2dp_rgb16_tile_fill_only(NULL,
                                &c_tileshuRGB565,       
                                ptTile,        
                                &myMapRegion);        
        }
        if(2 == Soul_Douluo_map[map_num].layer){
            //xue shan  
            myMapRegion.tLocation.iY -= (12+34+52+5+35);
            myMapRegion.tSize.iHeight = 52;
            myMapRegion.tSize.iWidth = 75;
            arm_2dp_rgb16_tile_copy_with_colour_keying_only(NULL,
                                &c_tilexueshan01RGB565,                                
                                ptTile,        
                                &myMapRegion,
                                GLCD_COLOR_BLACK);                   
        }
        if(3 == Soul_Douluo_map[map_num].layer){
            //xue shan 
            myMapRegion.tLocation.iY -= (12+34+52+5+70);
            myMapRegion.tSize.iHeight = 56;
            myMapRegion.tSize.iWidth = 55;
            arm_2dp_rgb16_tile_copy_with_colour_keying_only(NULL,
                                &c_tilexueshan02RGB565,                                
                                ptTile,        
                                &myMapRegion,
                                GLCD_COLOR_BLACK);                   
        }    
    }   
    if(bIsNewFrame){
        s_num++;
    }
    do{    //ren_jump_tile[4]        
        arm_2d_region_t myRegion ={
            .tLocation = {.iX = Soul_Douluo_PEOPLE_IX,.iY = 70},
            .tSize = {.iHeight = 43,.iWidth = 43},
        };
        
        myRegion.tLocation.iY = Soul_Douluo_Op.people_iY;
        if(Soul_Douluo_Op.jump_flag){
            arm_2dp_rgb16_tile_copy_with_colour_keying_and_x_mirror(NULL,
                            //&c_tileren01RGB565, 
                            ren_jump_tile[s_num & 3],
                            ptTile,        
                            &myRegion,
                            GLCD_COLOR_BLACK); 
        }else{
            arm_2dp_rgb16_tile_copy_with_colour_keying_and_x_mirror(NULL,
                            //&c_tileren01RGB565, 
                            ren_tile[(s_num/3) % 3],
                            ptTile,        
                            &myRegion,
                            GLCD_COLOR_BLACK); 
        }            
    }while(0);
    //xiao_ren_tile[4]
    
    do{//c_tilezd01RGB565
        int16_t i;
        static char zd_num = 0;
        arm_2d_region_t myRegion ={
            .tLocation = {.iX = 260,.iY = 70},
            .tSize = {.iHeight = 43,.iWidth = 34},
        };
        #define GLCD_COLOR_XIAOREN 0x2589
        for(i = 0; i < Soul_Douluo_ENEMY_NUM; i++ ){
            if(Soul_Douluo_enemys[i].flag == 1){
                myRegion.tLocation.iX = Soul_Douluo_enemys[i].iX - Soul_Douluo_Op.move_iX;
                myRegion.tLocation.iY = Soul_Douluo_enemys[i].iY;
                myRegion.tSize.iHeight = 43;
                myRegion.tSize.iWidth = 34;
                arm_2dp_rgb16_tile_copy_with_colour_keying_only(NULL,                            
                            xiao_ren_tile[(s_num>>1) & 3],
                            ptTile,        
                            &myRegion,
                            GLCD_COLOR_XIAOREN);
                //Soul_Douluo_enemys[num].level
                myRegion.tLocation.iY -= 12;
                myRegion.tSize.iHeight = 5;
                arm_2d_fill_colour(ptTile, &myRegion, GLCD_COLOR_BLUE);
                
                myRegion.tLocation.iX += 2;
                myRegion.tLocation.iY += 1;
                myRegion.tSize.iHeight = 3;
                myRegion.tSize.iWidth -= 4;
                myRegion.tSize.iWidth = Soul_Douluo_enemys[i].level/10*3;
                arm_2d_fill_colour(ptTile, &myRegion, GLCD_COLOR_RED);
            }else if(Soul_Douluo_enemys[i].flag == 2){
                //Soul_Douluo_sub_enemy(i);
                if(bIsNewFrame){
                    zd_num++;
                    if(zd_num > 2){
                        zd_num = 0;
                        Soul_Douluo_sub_enemy(i);
                    }
                }
                myRegion.tLocation.iX = Soul_Douluo_enemys[i].iX - Soul_Douluo_Op.move_iX;
                myRegion.tLocation.iY = Soul_Douluo_enemys[i].iY;
                myRegion.tSize.iHeight = 29;
                myRegion.tSize.iWidth = 38;
                arm_2dp_rgb16_tile_copy_with_colour_keying_only(NULL,                            
                            zd_tile[zd_num-1],
                            ptTile,        
                            &myRegion,
                            GLCD_COLOR_XIAOREN);
            }
        }
        
        
    }while(0);
    
    do{ //c_tilezhidanRGB565
        //Soul_Douluo_bullets[Soul_Douluo_bullets_NUM]
        arm_2d_region_t myRegion ={
            .tLocation = {.iX = 0,.iY = 0},
            .tSize = {.iHeight = 15,.iWidth = 17},
        };
        char i;
        for(i = 0; i < Soul_Douluo_bullets_NUM; i++ ){
            if(Soul_Douluo_bullets[i].flag){
                myRegion.tLocation.iX = Soul_Douluo_bullets[i].iX;
                myRegion.tLocation.iY = Soul_Douluo_bullets[i].iY;
                arm_2dp_rgb16_tile_copy_with_colour_keying_only(NULL,
                                &c_tilezhidanRGB565,                                
                                ptTile,        
                                &myRegion,
                                GLCD_COLOR_BLACK);            
            }
        }  
    }while(0);
                  
}

void Soul_Douluo_key_board_run(){
    switch(key_num){
        case 13:
            if(Soul_Douluo_Op.move_down_flag==0){
                Soul_Douluo_Op.jump_flag = 1;  
            }
        break;
        case 14:
            Soul_Douluo_Op.pause_flag = 0;    
        break;
        case 15:
            Soul_Douluo_Op.pause_flag = 1;    
        break;
        case 16:
            Soul_Douluo_Op.emit_flag = 1;    
        break;
    }
    key_num = 0;
}

void set_emit_flag(){
    Soul_Douluo_Op.emit_flag = 1; 
}

#endif
#if defined(__clang__)
#   pragma clang diagnostic pop
#endif

#endif

#endif

